package com.jinke.api.modules.third.shipBridge.util;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jinke.api.common.annotation.Apilog;
import com.jinke.api.modules.app.util.MathUtil;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.shipBridge.entity.request.ShipBridgeCancel;
import com.jinke.api.modules.third.shipBridge.entity.request.Dimensions;
import com.jinke.api.modules.third.shipBridge.entity.request.SenderAndRecipient;
import com.jinke.api.modules.third.shipBridge.entity.request.ShipBridge;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author huang
 * @data 2024-05-31
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ShipBridgeUtils {
    private static final String USER_NAME = "403379112@QQ.com";
    private static final String PASS_WORD = "Aa1234567";
    private static final String GET_PRICE_URL = "http://52.151.45.190:8000/api/rate";
    private static final String CANCEL_URL = "http://52.151.45.190:8000/api/void";
    private static final String CREATE_ORDER = "http://52.151.45.190:8000/api/create";

    @Apilog(requestTypeName = "shipbridge-估价")
    public  String getPrice(EstimateRateRequest request, String code) {
        //组装参数
        String body = getShipBridgePriceBody(request, code);
        log.info("ShipBridge 估价请求参数----------------->,{},{}", request.getOrderNO(), body);
        //发送请求
        try {
            String result = sendPostRequest(GET_PRICE_URL, body);
            log.info("ShipBridge 估价请求响应结果----------------->,{},{}", request.getOrderNO(), result);
            return result;
        } catch (Exception e) {
            log.info("ShipBridge 估价请求异常----------------->,{}", request.getOrderNO());
        }
        //返回结果
        return Strings.EMPTY;
    }

    /**
     * 取消
     * @param tackNumber
     * @param orderNo
     * @return
     */
    @Apilog(requestTypeName = "ShipBridge-取消")
    public String cancel(String tackNumber, String orderNo) {
        ShipBridgeCancel cancel = new ShipBridgeCancel();
        cancel.setTracking_code(tackNumber);
        //发送请求
        try {
            String param = JSON.toJSONString(cancel);
            log.info("----------------ShipBridge 取消订单请求参数----------------->{},{}", orderNo, param);
            String result = sendPostRequest(CANCEL_URL, param);
            log.info("----------------ShipBridge 取消订单响应结果----------------->{},{}", orderNo, result);
            return result;
        } catch (Exception e) {
            log.info("----------------ShipBridge 取消订单异常----------------->{},{}", orderNo, tackNumber);
        }
        //返回结果
        return Strings.EMPTY;
    }


    @Apilog(requestTypeName = "shipbridge-下单")
    public  String createOrder(EstimateRateRequest request, String code) {
        //组装参数
        String body = getShipBridgePriceBody(request, code);
        log.info("ShipBridge 下单请求参数----------------->,{},{}", request.getOrderNO(), body);
        //发送请求
        try {
            String result = sendPostRequest(CREATE_ORDER, body);
            log.info("ShipBridge 下单请求响应结果----------------->,{},{}", request.getOrderNO(), result);
            return result;
        } catch (Exception e) {
            log.info("ShipBridge 下单请求异常----------------->,{}", request.getOrderNO());
        }
        //返回结果
        return Strings.EMPTY;

         /*String result = "{\n" +
                "\"account_balance\":16.0,\n" +
                "\"currency\":\"USD\",\n" +
                "\"rate\":{\n" +
                "\"total\":4.0,\n" +
                "\"shipment\":4.0,\n" +
                "\"other\":0,\n" +
                "\"other_detail\":[\n" +
                "\"fixed rate\"\n" +
                "]\n" +
                "},\n" +
                "\"service\":\"ups_ground_ep\",\n" +
                "\"package\":\"package\",\n" +
                "\"zone\":8,\n" +
                "\"tracking_code\":[\n" +
                "\"1ZXRMNDK0311775769\"\n" +
                "],\n" +
                "\"label_url\":\"http://52.151.45.190:8000/media/labels/2024-05-31/105/68bc76ebcf7300f4efa1bfc57e94a54b.pdf\"\n" +
                "}";*/
    }

    private  String getShipBridgePriceBody(EstimateRateRequest request, String code) {
        ShipBridge shipBridge = new ShipBridge();
        //发件人
        SenderAndRecipient sender = getSender(request);
        shipBridge.setSender(sender);
        //收件人
        SenderAndRecipient recipient = getRecipient(request);
        shipBridge.setRecipient(recipient);
        //包裹信息
        List<Dimensions> dimensionsList = getDimensionsList(request);
        shipBridge.setDimensions(dimensionsList);
        shipBridge.setPak("package");
        shipBridge.setService(code);
        return JSON.toJSONString(shipBridge);
    }

    private  List<Dimensions> getDimensionsList(EstimateRateRequest request) {
        List<EstimateRateRequest.Parcel> parcels = request.getParcels();
        List<EstimateRateRequest.Parcel> newParcels = new ArrayList<>();
        for (EstimateRateRequest.Parcel parcel : parcels) {
            for (int i = 0; i < parcel.getPackageNum(); i++) {
                EstimateRateRequest.Parcel newP = new EstimateRateRequest.Parcel();
                BeanUtils.copyProperties(parcel, newP);
                newParcels.add(newP);
            }
        }
        List<Dimensions> dimensionsList = newParcels.stream().map(p -> {
            Dimensions dimensions = new Dimensions();
            //初始化原包裹数据
            BigDecimal weight = new BigDecimal(p.getWeight());
            BigDecimal length = new BigDecimal(p.getLength());
            BigDecimal width = new BigDecimal(p.getWidth());
            BigDecimal height = new BigDecimal(p.getHeight());
            //判断是否需要转化
            if ("cm".equals(p.getDistanceUnit())) {
                length = MathUtil.cm2in(length);
                width = MathUtil.cm2in(width);
                height = MathUtil.cm2in(height);
            }
            dimensions.setWeight("lb".equals(p.getMassUnit()) ? lbOrOz(weight) : kgOrOz(weight));
            dimensions.setLength(length);
            dimensions.setHeight(height);
            dimensions.setWidth(width);
            if (StringUtils.isNotEmpty(request.getExtra().getReference())) {
                dimensions.setReference1(request.getExtra().getReference());
            }
            if (StringUtils.isNotEmpty(request.getExtra().getReference2())) {
                dimensions.setReference1(request.getExtra().getReference2());
            }
            dimensions.setDelivery_confirmation(StringUtils.isNotBlank(request.getExtra().getSignatureOption()) ? request.getExtra().getSignatureOption() : "1");
            //复制返回
            return dimensions;
        }).collect(Collectors.toList());
        return dimensionsList;
    }

    @NotNull
    private  SenderAndRecipient getSender(EstimateRateRequest request) {
        SenderAndRecipient sender = new SenderAndRecipient();
        EstimateRateRequest.Address from = request.getFrom();
        sender.setName(from.getPersonName());
        sender.setAddress1(from.getAddressLine1());
        sender.setAddress2(StringUtils.isNotBlank(from.getAddressLine2()) ? from.getAddressLine2() : null);
        sender.setCity(from.getCity());
        sender.setState(from.getStateCode());
        sender.setPostal_code(from.getZipCode());
        sender.setCountry_code(from.getCountryCode());
        return sender;
    }

    @NotNull
    private  SenderAndRecipient getRecipient(EstimateRateRequest request) {
        EstimateRateRequest.Address to = request.getTo();
        SenderAndRecipient recipient = new SenderAndRecipient();
        recipient.setAddress1(to.getAddressLine1());
        recipient.setName(to.getPersonName());
        recipient.setAddress2(StringUtils.isNotBlank(to.getAddressLine2()) ? to.getAddressLine2() : null);
        recipient.setCity(to.getCity());
        recipient.setState(to.getStateCode());
        recipient.setPostal_code(to.getZipCode());
        recipient.setCountry_code(to.getCountryCode());
        return recipient;
    }


    private  BigDecimal kgOrOz(BigDecimal weight) {
        return weight.multiply(new BigDecimal("35.27396")).setScale(2, RoundingMode.UP);
    }

    private  BigDecimal lbOrOz(BigDecimal weight) {
        return weight.multiply(new BigDecimal("16")).setScale(2, RoundingMode.UP);
    }

    /**
     * Post
     *
     * @param url  路径
     * @param body 请求体
     * @return 结果
     * @throws IOException io
     */
    public  String sendPostRequest(String url, String body) throws IOException {
        HttpURLConnection connection = null;
        try {
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 10809));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }
            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", getAuth());
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(body.getBytes("UTF-8"));
            }

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
                // 获取错误消息体
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
                    StringBuilder errorResponse = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                    return errorResponse.toString();
                }
            } else {
                // 获取正常响应
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    return response.toString();
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    public  String getAuth() {
        String authString = USER_NAME + ":" + PASS_WORD;
        String encodedAuth = Base64.getEncoder().encodeToString(authString.getBytes(StandardCharsets.UTF_8));
        return "Basic " + encodedAuth;
    }
}
